import { create } from '@prequest/miniprogram'
import Lock from '@prequest/lock'
import { useAppStore, useUserStore } from '@/stores'
import { lock as loginLock } from './login'
import serverConf from '@/config'

uni.setStorageSync('app-init-status', false)

const http = create(uni.request, {
  baseURL: serverConf.api,
  // header: {
  //   'Content-Type': 'application/x-www-form-urlencoded',
  // },
})

export const lock = new Lock({
  getValue () {
    return Promise.resolve(uni.getStorageSync('app-init-status'))
  },
  setValue (status) {
    uni.setStorageSync('app-init-status', status)
  },
  clearValue () {
    uni.removeStorageSync('app-init-status')
  },
})

let errCount = 0
function errMsgHandler () {
  loginLock.clear()
  lock.clear()
  if (errCount === 0) {
    uni.showModal({
      title: '提示',
      content: '出错了，请稍后再试',
      showCancel: false,
    })
  }
  errCount++
}

export async function init () {
  const appStore = useAppStore()
  const userStore = useUserStore()

  interface ResponseData {
    code: number,
    data: any
  }

  http.use(async (ctx, next) => {
    ctx.request.header = ctx.request.header || {}
    ctx.request.header['im-token'] = uni.getStorageSync('im-token')
    await next()
  })

  const appId = appStore.appInfo.appId
  const resolvedPromises = await Promise.allSettled([
    http.get<ResponseData>('/authority-manager/applet-config/get'),
    http.get<ResponseData>('/project-business/applets/projects', { data: { appId } }),
    http.get<ResponseData>('/user-info/visitors/information'),
  ])
  resolvedPromises.forEach((p, i) => {
    if (p.status === 'fulfilled') {
      const { code, data } = p.value.data
      i === 0 && code === 200 && appStore.setAppConfig(data) // 初始化小程序配置信息
      i === 0 && code !== 200 && errMsgHandler()

      i === 2 && code === 200 && userStore.setUserInfo(data) // 初始化用户信息
      i === 2 && code !== 200 && errMsgHandler()
      // TODO
    } else {
      // TODO
    }
  })

  return true
}

const wrapper = Lock.createLockWrapper(lock)

export const appInit = () => wrapper(init)
